package com.transfiguro.core;


import ch.qos.logback.core.StopWatch;
import com.transfiguro.Converter;
import com.transfiguro.Writer;
import com.transfiguro.datamodel.csmodels.CSClassModel;
import com.transfiguro.datamodel.csmodels.CSMethod;
import com.transfiguro.datamodel.javamodels.ClassModel;
import com.transfiguro.parser.CoreParser;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.core.convert.ConversionException;

import java.io.File;

/**
 * This class represents the core of the tool. Conversion of Java to C# will begin in this class
 */
public class Core {
    /**
     * The logger used throughout this class
     */
    private static final Logger LOGGER = LoggerFactory.getLogger(Core.class);
    private Configuration configuration;
    private ClassPathXmlApplicationContext ctx;

    /**
     * Constructor
     */
    public Core() {
        ctx = new ClassPathXmlApplicationContext("ConversionContext.xml");
        configuration = (Configuration) ctx.getBean("config_1");
    }

    /**
     * This method will do the necessary steps to convert the files listed
     * in {@link Configuration} to C#
     */
    public void convert() throws ConversionException {
        final StopWatch stopWatch = new StopWatch("ConversionTimer");
        final Analyzer analyzer = new Analyzer();

        for (final File file : configuration.getFiles()) {
            final CoreParser parser = new CoreParser(file);
            final StopWatch classConversionTimer = new StopWatch("ClassConversionTimer");
            final ClassModel classModel = parser.parse();
            final Converter converter = new Converter();
            converter.convertToCS(classModel);
            final CSClassModel csClassModel = converter.getCsClassModel();
            stopWatch.stop();
            csClassModel.setConversionTime(stopWatch.getResultInSeconds());
            for (final CSMethod method : csClassModel.getMethods()) {
                //LOGGER.info("Method: \n{}", method.toString());
                LOGGER.info("Name: {}", method.toString());
            }
            final Writer writer = new Writer(csClassModel);
            writer.writeFile();

            LOGGER.info("Statistics: \n{}", analyzer.getStatistics(csClassModel));
        }
        stopWatch.stop();
        LOGGER.info("Conversion time: {}s", stopWatch.getResultInSeconds());
    }

    /**
     * This method returns the converted {@link CSClassModel} instance
     * from the given java file. This method is now called from the UI
     *
     * @param file The java file from which the csClassModel instance has to be returned
     * @return The instance of csClassModel created from the java file
     */
    public CSClassModel getConvertedFile(final File file) {
        final CoreParser parser = new CoreParser(file);
        final ClassModel classModel = parser.parse();
        final Converter converter = new Converter();
        converter.convertToCS(classModel);
        final CSClassModel csClassModel = converter.getCsClassModel();
        return csClassModel;
    }

    /**
     * The method is the entry point
     *
     * @param args Optional arguments that can be passed
     */
    public static void main(final String[] args) {
        final Core conversionCore = new Core();
        try {
            conversionCore.convert();
        } catch (final ConversionException e) {
            LOGGER.error("Error in conversion: {}", e.getMessage());
        }
    }

}
